package cs4game;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import org.lwjgl.opengl.GL11;
import org.newdawn.slick.opengl.Texture;
import org.newdawn.slick.opengl.TextureLoader;

public class BlockID {

	//Blocks are integers in format 0x12345678 where 123 is the block ID, 
	//4 is the lighting (0-F), 5 is collides (1 or 3) && opaque (2 or 3), 67 is damage, and 8 is metadata
	//def[0] = texture vs def[1] = 3D vertexes
	//def[n] = sides
	//def[n][n] = vertex
	//def[n][n][n] = coordinate components
	public static final int BOTTOM = 0, ZBACK = 1, XFRONT = 2, ZFRONT = 3, XBACK = 4, TOP = 5;
	double[][][][] def;
	protected Texture tex; 
	protected float n[][] = {
			{0, 0, 1}, {0, 1, 0}, {0, 0, -1},
			{0, -1, 0}, {-1, 0, 0}, {1, 0, 0}};

	public BlockID(double[][][][] d){
		def = d;
		tex = World.tex;
	}

	public void draw(Vector3D loc, int key, World world){

		//System.out.println(loc+": "+key);
		//int light = (int) (Math.pow(0.8, (0xF-getLighting(key)))*255);
		//int sideLight = (int) (light*0.8);
		//int bottomLight = (int) (sideLight*0.8);
		//GL11.glColor3f(light, light, light);
		//GL11.glColor3f(255,255,255);
		GL11.glBegin(GL11.GL_QUADS);
		if(def.length>0)
			for(int i = 0; i< def[0].length; i++){
				Integer adjID = world.getBlock(getPoint(i, loc));
				if(adjID != -1){
					BlockID adjDef = BlockDefs.get(world.getID(adjID));
					if(adjDef.isOpaque(adjID))
						for(int j = 0; j< def[0][i].length; j++){
							//GL11.glNormal3f(n[i][0], n[i][1], n[i][2]);
							GL11.glTexCoord2d(def[0][i][j][0], def[0][i][j][1]);
							GL11.glVertex3d(def[1][i][j][0]+loc.x, def[1][i][j][1]+loc.y, def[1][i][j][2]+loc.z);
						}
				}
				else
					for(int j = 0; j< def[0][i].length; j++){
						//GL11.glNormal3f(n[i][0], n[i][1], n[i][2]);
						GL11.glTexCoord2d(def[0][i][j][0], def[0][i][j][1]);
						GL11.glVertex3d(def[1][i][j][0]+loc.x, def[1][i][j][1]+loc.y, def[1][i][j][2]+loc.z);
					
					}
			
			}
		GL11.glEnd();
	}
	
	public void drawSide(Vector3D loc, int key, int side, World world){
		GL11.glBegin(GL11.GL_QUADS);
		Integer adjID = world.getBlock(getPoint(side, loc));
		if(adjID != -1){
			BlockID adjDef = BlockDefs.get(world.getID(adjID));
			if(adjDef.isOpaque(adjID))
				for(int j = 0; j< def[0][side].length; j++){
					//GL11.glNormal3f(n[side][0], n[side][1], n[side][2]);
					GL11.glTexCoord2d(def[0][side][j][0], def[0][side][j][1]);
					GL11.glVertex3d(def[1][side][j][0]+loc.x-0.5, def[1][side][j][1]+loc.y-0.5, def[1][side][j][2]+loc.z-0.5);
				}
		}
		else
			for(int j = 0; j< def[0][side].length; j++){
				//GL11.glNormal3f(n[side][0], n[side][1], n[side][2]);
				GL11.glTexCoord2d(def[0][side][j][0], def[0][side][j][1]);
				GL11.glVertex3d(def[1][side][j][0]+loc.x-0.5, def[1][side][j][1]+loc.y-0.5, def[1][side][j][2]+loc.z-0.5);
			
			}
		GL11.glEnd();
	}
	
	public Vector3D getPoint(int dir, Vector3D loc){
		switch (dir){
			case BOTTOM:
				return new Vector3D(loc.x, loc.y-1, loc.z);
			case TOP:
				return new Vector3D(loc.x, loc.y+1, loc.z);
			case ZFRONT:
				return new Vector3D(loc.x, loc.y, loc.z+1);
			case ZBACK:
				return new Vector3D(loc.x, loc.y, loc.z-1);
			case XFRONT:
				return new Vector3D(loc.x+1, loc.y, loc.z);
			case XBACK:
				return new Vector3D(loc.x-1, loc.y, loc.z);
			default:
				return loc;
		
		}
		
		
	}
	
	public boolean isOpaque(int key){return ((key & (0x0000F000))>>24)>0x1;}
	
	
	public BoundingBox getBoundingBox(Vector3D loc, int key){
		return new BoundingBox(new Vector3D(loc.x-0.5, loc.y-0.5, loc.z-0.5), new Vector3D(loc.x+0.5, loc.y+0.5, loc.z+0.5));
	}
	

	public int setCollides(int block, boolean c){
		int t = 0;
		if(c) t = 1;
		return (block & (0xFFFF0FFF + t*0x1000));
	}
	public boolean getCollides(int block){return (((block & 0x00001000)>>24)%0x2 == 1);}

	public int setLighting(int block, int l){
		if(l>0xF) l=0xF;
		else if(l<0x0) l= 0x0;		
		return (block & (0xFFF0FFFF + l*0xF0000));	
	}
	public int getLighting(int block){return ((block & 0x000F0000)>>32);}


}
